#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

//static_cast 静态类型转换
//int main()
//{
//	int i = 1;
//	double d = 3.14;
//
//	//static_cast只能对相似类型进行转换
//	//对于一些不相似的类型不可使用 使用该类型转换比较安全
//	i = static_cast<int>(d);
//	cout << i << endl;
//	return 0;
//}


//reinterpret_cast 重新解释类型转换
//int main()
//{
//	int a = 0x11223344;
//	int* pa = nullptr;
//
//	//pa = static_cast<int*>(a); //无效类型转换
//	//pa = (int*)a; //强制类型转换可以 但是不安全
//	pa = reinterpret_cast<int*>(a); //安全的类型转换
//	//用于不相似的类型转换 
//
//	return 0;
//}


//const_cast 去掉const属性转换
//int main()
//{
//	//volatile去掉编译器优化
//	volatile const int a = 2; //这里编译器可能会做优化 因为a不会修改 所以a的值被保存在寄存器中 去掉优化强制让编译器每次都去内存中读取
//	int* pa = const_cast<int*>(&a);
//	//int* pa = (int*)&a; //强制类型转换也是可以的 但不安全
//	*pa = 3;
//
//	cout << a << endl; 
//	cout << *pa << endl;
//
//	return 0;
//}


//dynamic_cast 动态转换 - 只能对多态类型转换(继承+虚函数)
//class A
//{
//public:
//	A(int a = 0) :_a(a) {}
//
//	virtual void func() {}
//
//protected:
//	int _a;
//};
//
//class B:public A
//{
//public:
//	B(int a = 0,int b = 0) :A(a),_b(b) {}
//	virtual void func() {}
//protected:
//	int _b;
//};
//
//
////在多态下 父类指针或引用可以指向子类 默认支持下转型 但是上转型不支持
//void test(A& obj)
//{
//	//B* b = (B*)(&obj); //这里可以使用强制类型转换
//	//但是如果子类有自己的成员 此时传递A对象就会出现野指针问题 因为A中没有子类B的成员 但是却是B类型指针
//
//	//dynamic_cast如果转换成功 返回转换的对象 如果不能转换则返回空
//	//一般用在多态下，虽然是父类指针或引用指向子类 但是在函数中要使用子类指针操控自己的函数时使用转换
//	B* b = dynamic_cast<B*>(&obj);
//
//	cout << "原地址" << &obj << endl;
//	cout << "转换后" << b << endl;
//
//}
//
//int main()
//{
//	A a;
//	B b;
//	cout << "a对象:" << endl;
//	test(a); //a不能转换为B指针 所以转换失败为空指针
//	cout << "b对象:" << endl;
//	test(b);
//	return 0;
//}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//cin返回值
//int main()
//{
//	string s;
//	while (cin >> s)
//	{
//		cout << s << endl;
//	}
//	//instream中重载了operator bool运算符 实现逻辑判断值的类型转换
//	return 0;
//}

//class test
//{
//public:
//	test(int a = 0):_a(a) {}
//
//	operator int() //控制类型转换的返回值 当test对象转换为int对象时返回-1
//	{
//		return -1;
//	}
//
//	explicit operator double()
//	{
//		return 3.14;
//	}
//
//	int _a;
//};
//
//int main()
//{
//	test t = 1; //隐式类型转换
//	int a = t;
//	double d = (double)t;
//	cout << "a=" << a << endl;
//	cout << "d=" << d << endl;
//	return 0;
//}


//普通打开 写入
//int main()
//{
//	fstream iof("./text.txt", ios_base::in | ios_base::out | ios_base::trunc); //以读写的方式打开 没有文件则创建
//	//iof.open("./text.txt", ios_base::in | ios_base::out | ios_base::trunc);
//	iof << "hello word" << endl;
//	iof << "668" << endl;
//	iof << "zmy" << endl;
//
//	iof.seekp(ios_base::beg); //将流指向文件开头
//	string s;
//	iof >> s;
//	cout << s << endl;
//
//	iof >> s;
//	cout << s << endl;
//
//	iof >> s;
//
//	cout << s << endl;
//	return 0;
//}

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	operator bool() const
	{
		// 这里是随意写的，假设输入_year为0，则结束
		if (_year == 0)
			return false;
		else
			return true;
	}

	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& out, Date& d)
{
	out << d._year << " " << d._month <<" " << d._day;
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

//
//struct ServerInfo
//{
//	char _address[32] = {0};
//	//string _address;
//
//	//二进制写入不能使用string string中保存的是内存指针 写入内存指针 下次读取的时候就是野指针
//	//因此string文本要是有文本读写 也就是<<和>>
//
//	int _port = 0;
//	Date _date = {0,0,0};
//
//	void print()
//	{
//		cout << _address << endl;
//		cout << _port << endl << endl;
//		cout << "date:" << endl;
//		cout << _date._year << endl;
//		cout << _date._month << endl;
//		cout << _date._day << endl;
//
//
//
//	}
//
//};
//
////二进制读写
//void wr()
//{
//	ServerInfo info = { "192.0.0.1", 80, { 2023, 7, 11 } };
//	ofstream iof("./text.txt", ios_base::out | ios_base::trunc | ios_base::binary); //二进制打开
//	iof.write((char*)(&info), sizeof(info));
//}
//
//void re()
//{
//	ServerInfo info;
//	ifstream iof("./text.txt", ios_base::in | ios_base::binary); //二进制打开
//	iof.read((char*)(&info), sizeof(info));
//	info.print();
//}
//
////文本读写
//void wrtxt()
//{
//	ServerInfo info = { "192.0.0.1", 80, { 2023, 7, 11 } };
//	ofstream iof("./text.txt", ios_base::out | ios_base::trunc);
//	iof << info._address << endl;
//	iof << info._port << endl;
//	iof << info._date._year << endl;
//	iof << info._date._month << endl;
//	iof << info._date._day << endl;
//}
//
//void retxt()
//{
//	ServerInfo info;
//	ifstream iof("./text.txt", ios_base::in);
//	iof >> info._address;
//	iof >> info._port;
//	iof >> info._date._year;
//	iof >> info._date._month;
//	iof >> info._date._day;
//	info.print();
//}
//
//
//int main()
//{
//	wrtxt();
//	retxt();
//	return 0;
//}


struct ChatInfo
{
	string _name; // 名字
	int _id;      // id
	Date _date;   // 时间
	string _msg;  // 聊天信息
};


void strwrite(stringstream& s, ChatInfo& info)
{
	s << info._name << endl; //换行或空格 截断
	s << info._id << endl;
	s << info._msg << endl;
	s << info._date << endl;
}

void strread(stringstream& s, ChatInfo& info)
{
	s >> info._name;
	s >> info._id;
	s >> info._msg;
	s >> info._date;
}

int main()
{
	ChatInfo info = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧" };
	stringstream ins;
	strwrite(ins, info);

	string buf = ins.str();
	cout << buf << endl;

	ChatInfo outinfo;
	stringstream outs(buf);
	strread(outs, outinfo);

	cout << "--------------------------------------------------------" << endl;
	cout <<"时间：" << outinfo._date << endl;
	cout << "id:" << outinfo._id << "|";
	cout << outinfo._name << ": ";
	cout << outinfo._msg << endl;
	cout << "--------------------------------------------------------" << endl;

	return 0;
}